#include "constructor.h"

int TConstructor_Crear( struct TConstructor *tc){
/**PRE: -Ninguna
/**POST -El constructor ha sido creado*/
    tc->eventoAnterior = CB_NO_EVENTO;
    tc->indicador = 0;

    TConstructor_SetCola(tc,&(tc->cola));
    TlistaReporte_Crear(&(tc->reporte),sizeof(Reporte));

    return 0;
}

int TConstructor_DiccionarioCrear(struct TConstructor *tc){
    tc->diccionario = (TDiccionario*) malloc(sizeof(TDiccionario));

    if(!tc->diccionario)
        return FALSE;
    return TRUE;
}

int TConstructor_Destruir(struct TConstructor *tc){
/**PRE: -El constructor ha sido creado
/**POST -Se liberan recursos asociados*/

    TlistaReporte_Vaciar(&(tc->reporte));
    return 0;
}

int TConstructor_SetCola(struct TConstructor *tc, TCola *cola){
/**PRE: -El constructor ha sido creado
/**POST -Se establece la estructura de cola donde se colocaran los tweets en formato TDiccionario*/
    C_Crear(&(tc->cola), sizeof(TDiccionario));
    return 0;
}


/***********************************************************************************************/
/*********************************EVENTOS*******************************************************/
/***********************************************************************************************/

int TConstructor_ComienzaArray(struct TConstructor *tc, void *dato){
    tc->indicador++;
    return 0;
}

int TConstructor_TerminaArray(struct TConstructor *tc, void *dato){
    tc->indicador--;
    return 0;
}

int TConstructor_ComienzaObjeto(struct TConstructor *tc, void *dato){
    if(tc->indicador++ == 1){
        if(TConstructor_DiccionarioCrear(tc)) /*malloc a tc->diccionario*/
            TDiccionario_Crear(tc->diccionario);
    }
    return 0;
}

int TConstructor_TerminaObjeto(struct TConstructor *tc,  void *dato){
    if(--tc->indicador == 1){
        C_Agregar(&(tc->cola), tc->diccionario);
        free(tc->diccionario);
    }
    return 0;
}


int TConstructor_Clave(struct TConstructor *tc, void *dato){
    if(tc->eventoAnterior == CB_CLAVE)
        TDiccionario_LiberarClave(tc->diccionario);

    TDiccionario_GuardarClave(tc->diccionario,dato);

    tc->eventoAnterior = CB_CLAVE;
    return 0;
}

int TConstructor_True(struct TConstructor *tc, void *dato){
    TDiccionario_GuardarValor(tc->diccionario,"TRUE");
    TDiccionario_Colocar(tc->diccionario);
    tc->eventoAnterior = CB_TRUE;
    return 0;

}

int TConstructor_False(struct TConstructor *tc, void *dato){

    TDiccionario_GuardarValor(tc->diccionario,"FALSE");
    TDiccionario_Colocar(tc->diccionario);
    tc->eventoAnterior = CB_FALSE;
    return 0;

}

int TConstructor_Null(struct TConstructor *tc, void *dato){

    TDiccionario_GuardarValor(tc->diccionario,"NULL");
    TDiccionario_Colocar(tc->diccionario);
    tc->eventoAnterior = CB_NULL;
    return 0;
}

int TConstructor_Numero(struct TConstructor *tc, void *dato){

    TDiccionario_GuardarValor(tc->diccionario,dato);
    TDiccionario_Colocar(tc->diccionario);
    tc->eventoAnterior = CB_NUMERO;
    return 0;
}

int TConstructor_String(struct TConstructor *tc, void *dato){
    TDiccionario_GuardarValor(tc->diccionario,dato);
    TDiccionario_Colocar(tc->diccionario);
    tc->eventoAnterior = CB_STRING;
    return 0;

}


/********************************Impresion de listado********************************/
int TConstructor_ImprimirListado(struct TConstructor *tc){

    struct Reporte Reporte;
    char* clave = (char*) malloc(sizeof(char)*strlen("screen_name"));
    struct TDiccionario* corriente = (TDiccionario*) malloc(sizeof(TDiccionario));

    strcpy(clave,"screen_name");

    while(C_Sacar(&(tc->cola),corriente)){
        Reporte.Usuario = (char*) malloc(TDiccionario_SizeDato(corriente, clave));
        Reporte.CantTweets = 1;

        TDiccionario_Obtener(corriente, clave, Reporte.Usuario);
        TlistaReporte_Insertar(&(tc->reporte),Reporte);

        /*El diccionario se destruye en este momento porque sino se pierde la referencia
          a todos los mallocs hechos cuando se construyo.*/
        TDiccionario_Destruir(corriente);
    }

    TlistaReporte_Imprimir(&(tc->reporte));

    free(clave);
    free(corriente);
    return 0;
}

